package com.module.TraceSource.manager;


import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.codehaus.jackson.JsonNode;
import org.hibernate.Session;
import org.hibernate.Transaction;

import com.module.TraceSource.dao.TsCodeForRecordDao;
import com.module.TraceSource.dao.TsEntEventItemDao;
import com.module.TraceSource.dao.TsEventItemRecordDao;
import com.module.TraceSource.dao.TsEventRecordDao;
import com.module.TraceSource.model.TraceSourceBeanUtil;
import com.module.TraceSource.vo.TsCodeForRecord;
import com.module.TraceSource.vo.TsEntEventItem;
import com.module.TraceSource.vo.TsEventItemRecord;
import com.module.TraceSource.vo.TsEventRecord;

import base.dao.GenericHibernateDao;
import base.manager.GenericHibernateManager;
import base.util.ResolveUnit;
import base.util.Tools;



public class TsEventItemRecordManager extends GenericHibernateManager<TsEventItemRecord, Long>{
	private TsEventItemRecordDao dao = TsEventItemRecordDao.getInstance();
	private TsEntEventItemDao eventItemdao = TsEntEventItemDao.getInstance();
	private static TsEventItemRecordManager service;
	public TsEventItemRecordManager() {
		super();
	}
	
	private TsEventRecordDao recordDao = TsEventRecordDao.getInstance();
	private TsCodeForRecordDao tsCodeForRecordDao = TsCodeForRecordDao.getInstance();
	public synchronized static TsEventItemRecordManager getInstance(){
		if(service == null){
			service = new TsEventItemRecordManager();
		}
		return service;
	}

	@Override
	public GenericHibernateDao<TsEventItemRecord, Long> getDao() {
		return dao;
	}
	
	//动态替换字符串
	private String formatDesc(String desc,String eventName,String columnval,String createTime,String colName){
		 Pattern p = Pattern.compile("#.*#");
		 Matcher m = p.matcher(desc);
		 String firstDesc=m.replaceAll(eventName);
		 
		 Pattern p$ = Pattern.compile("%d_createtime%");
		 Matcher m$ = p$.matcher(firstDesc);
		 firstDesc=m$.replaceAll(createTime);

		 Pattern p1 = Pattern.compile("%"+colName+"%");
		 
		 Matcher m1 = p1.matcher(firstDesc);
		 return m1.replaceFirst(columnval);
		 
		 
	}

	/**
	 * 溯源查询(平台上)
	 * @param bean
	 * @return
	 * @throws Exception
	 */
	public List listTsEventItemRecordByValue(TsEventItemRecord bean)throws Exception{
		Session session=getSession();
		List<TsEventItemRecord> returnList = new ArrayList<TsEventItemRecord>();
		List<TsEventItemRecord> al = new ArrayList<TsEventItemRecord>();
		try {
			String colval=bean.getColumnVal();
			boolean exist=dao.isExist(session,colval);//商品码查询是否存在
			if(exist){
				String orgPid = bean.getOrgPid();
				TsEventItemRecord vo=dao.findTsEventItemRecordByColVal(session,bean);
				//获得类型
				String type = vo.getType();
				if("PRODUCT".equalsIgnoreCase(type)){
					List<Long> list=this.getAllRecoidId(vo.getEventid());
					al = dao.findTsEventItemRecordByValue(session, list);
					
					Map<String,TsEventRecord> eventRecordMap = changeEventRecord(al);
					for(Map.Entry<String, TsEventRecord> entity : eventRecordMap.entrySet()){
						TsEventRecord eventRecord = entity.getValue();
						String desc= eventRecord.getDesc();//模板
						String eventName =eventRecord.getEventName();//动作
						String createTime = eventRecord.getCreatetime().toString();
						StringBuffer endDesc = new StringBuffer();
						String descBuf = new String(desc);
						//endDesc.append(eventRecord.getCreatetime());
						for(TsEventItemRecord tsEventItemRecord : eventRecord.getChildren()){
							String columnval= tsEventItemRecord.getColumnVal();//码值
							TsCodeForRecord tcfr=tsCodeForRecordDao.findTsCodeForRecordByCode(session, columnval);//获得码对应的信息
							String name="";
							if(tcfr!=null){
								name = tcfr.getName();
							}
							String itemType = tsEventItemRecord.getType();
							if(tcfr!=null){
								name = tcfr.getDesc();
								//eventName = tcfr.getDesc();
							}
							if(itemType.equals("TEXT")|| itemType.equals("PRODUCT")){
								name=columnval;
							}
							descBuf = formatDesc(descBuf, eventName, name,createTime,tsEventItemRecord.getColumnName());
						}
						//endDesc.append("\t"+descBuf);
						endDesc.append(descBuf);
						TsEventItemRecord temp = new TsEventItemRecord();
						temp.setReplacedDesc(endDesc.toString());
						returnList.add(temp);
					}
					
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
			throw e;
		}finally{
			this.closeSession();
		}
		return returnList;
	}
	/**
	 * 手机端获取溯源信息
	 * @param bean
	 * @return
	 * @throws Exception
	 */
	public TraceSourceBeanUtil findTsEventItemRecordByValue(TraceSourceBeanUtil bean)throws Exception{
		Session session=getSession();
		List returnList = new ArrayList();
		List<TsEventItemRecord> al = new ArrayList<TsEventItemRecord>();
		try {
			String colval=bean.getTsEventItemRecord().getColumnVal();
			boolean exist=dao.isExist(session,colval);
			if(exist){
				TsEventItemRecord vo=dao.findTsEventItemRecordByColVal(session, bean.getTsEventItemRecord());
				//获得类型
				String type = vo.getType();
				if("PRODUCT".equalsIgnoreCase(type)){
					List<Long> list=this.getAllRecoidId(vo.getEventid());
					al = dao.findTsEventItemRecordByValue(session, list);
					Map<String,TsEventRecord> eventRecordMap = changeEventRecordForPhone(al);
					//拿到值后替换
					for(Map.Entry<String, TsEventRecord> entity : eventRecordMap.entrySet()){
						//TsEventItemRecord tsEventItemRecord=al.get(i);
						TsEventRecord eventRecord = entity.getValue();
						//System.out.println("描叙:"+tsEventItemRecord.getDesc()+"--------"+tsEventItemRecord.getTsEventRecord().getEventName()+":"+tsEventItemRecord.getColumnVal());
						String desc= eventRecord.getDesc();//模板
						String eventName = eventRecord.getEventName();//动作
						String createTime = eventRecord.getCreatetime().toString();
						StringBuffer endDesc = new StringBuffer();
						String descBuf = new String(desc);
						//endDesc.append(eventRecord.getCreatetime());
						for(TsEventItemRecord tsEventItemRecord : eventRecord.getChildren()){
							String columnval= tsEventItemRecord.getColumnVal();//码值
							TsCodeForRecord tcfr=tsCodeForRecordDao.findTsCodeForRecordByCode(session, columnval);//获得码对应的信息
							String name="";
							if(tcfr!=null){
								name = tcfr.getName();
							}
							String itemType = tsEventItemRecord.getType();
							if(tcfr!=null){
								name = tcfr.getDesc();
							}
							
							if(itemType.equals("TEXT") || itemType.equals("PRODUCT")){
								name=columnval;
							}
							descBuf = formatDesc(descBuf, eventName, name,createTime,tsEventItemRecord.getColumnName());
						}
						//endDesc.append("\t"+descBuf);
						endDesc.append(descBuf);
						returnList.add(endDesc.toString());
					}
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
			throw e;
		}finally{
			this.closeSession();
		}
		bean.setList(returnList);
		return bean;
	}
	/**
	 * 把item转为event
	 * @param al
	 * @return
	 */
	private Map<String, TsEventRecord> changeEventRecord(List<TsEventItemRecord> al) {
		List<TsEventRecord> set = new LinkedList<TsEventRecord>();
		Map<String, TsEventRecord> map = new LinkedHashMap<String, TsEventRecord>();
		Session session=getSession();
		for(TsEventItemRecord item : al){
			if(map.containsKey(item.getEventid().toString())){
				TsEventRecord record = map.get(item.getEventid().toString());
				record.getChildren().add(item);
			}else{
				TsEntEventItem entitem = eventItemdao.get(session, item.getItemid());
				if(entitem!=null&&entitem.getIsTraceSource().equals("Y")){
				TsEventRecord record = item.getTsEventRecord();
				if(Tools.isValid(record)){
					record.setDesc(item.getDesc());
					record.getChildren().add(item);
					map.put(record.getId().toString(), record);
				}
			 }
				
			}
		}
		return map;
	}
	/**
	 * 把item转为event 手机端显示
	 * @param al
	 * @return
	 */
	private Map<String, TsEventRecord> changeEventRecordForPhone(List<TsEventItemRecord> al) {
		List<TsEventRecord> set = new LinkedList<TsEventRecord>();
		Map<String, TsEventRecord> map = new LinkedHashMap<String, TsEventRecord>();
		Session session=getSession();
		for(TsEventItemRecord item : al){
			if(map.containsKey(item.getEventid().toString())){
				TsEventRecord record = map.get(item.getEventid().toString());
				record.getChildren().add(item);
			}else{
				TsEntEventItem entitem = eventItemdao.get(session, item.getItemid());				
				TsEventRecord record = item.getTsEventRecord();
				if(Tools.isValid(record)){
					if(entitem!=null&&entitem.getIsTraceSource().equals("Y")){
						record.setDesc(item.getDesc());
					}else{
						record.setDesc("");
					}
					record.getChildren().add(item);
					map.put(record.getId().toString(), record);
				}
			}
		}
		return map;
	}
	/**
	 * 根据某一步的事件编号获得前面所有的事件编号，第一步的事件id放在最后面,最后的事件id放在最前。
	 * @param recordId
	 * @return
	 * @throws Exception
	 */
	private List<Long> getAllRecoidId(Long recordId)throws Exception{
		List<Long> list = new ArrayList<Long>();
		list.add(recordId);
		Session session=getSession();
		getCurParent(session,list,recordId);
		getCurChildren(session,list,recordId);
		return list;
	}
	
	/**
	 * 获得当前上级事件
	 * @param session
	 * @param list
	 * @param curRecordId
	 */
	private void getCurParent(Session session,List<Long> list,Long curRecordId){
		Long pid=this.recordDao.get(session, curRecordId).getpId();
		if(pid!=null){
			TsEventRecord temp=this.recordDao.get(session, pid);
			Long id=temp.getId();
			list.add(id);
			getCurParent(session,list,id);
		}
	}
	
	/**
	 * 获得当前下级事件
	 * @param session
	 * @param list
	 * @param curRecordId
	 */
	private void getCurChildren(Session session,List<Long> list,Long curRecordId){
		TsEventRecord result = null;
		//Long cid=this.recordDao.get(session, curRecordId).getpId();"from TsEventRecord obj "
		List<TsEventRecord> childrenList = recordDao.findBySQL(session, "from TsEventRecord obj where obj.pId="+curRecordId);
		if(childrenList!=null && childrenList.size()>0){
			TsEventRecord temp=childrenList.get(0);
			Long id=temp.getId();
			list.add(id);
			getCurChildren(session,list,id);
		}
	}

}
